package cn.bisoft.java.util.common;

import java.text.NumberFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.ArrayList;
import java.util.List;
import java.util.TimeZone;

public class StringUtil {

	/**
	 * <pre>
	 * GTech加密转码
	 * </pre>
	 * 
	 * @param ba
	 * @return
	 */
	public static String toHex(byte[] ba) {
		char hexdigit[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
				'a', 'b', 'c', 'd', 'e', 'f' };
		StringBuffer sb = new StringBuffer("");
		for (int i = 0; i < ba.length; i++) {
			sb.append(hexdigit[(ba[i] >> 4) & 0x0F]);
			sb.append(hexdigit[ba[i] & 0x0F]);
		}
		return sb.toString();
	}

	/**
	 * @param str
	 *            源字符串
	 * @param reg
	 *            正则表达式
	 * @return int 字符串str中包含的reg个数
	 */
	public static int count(String str, String reg) {
		int count = 0;
		Pattern expression = Pattern.compile(reg); // 使用表达式过滤字符串string1
		Matcher matcher = expression.matcher(str);
		while (matcher.find()) {
			count++;
		}
		return count;
	}

	/**
	 * <pre>
	 * 送票终端的时间是否可以送票
	 * </pre>
	 * 
	 * @param start
	 * @param end
	 * @return
	 */
	public static boolean isNotCanLottery(int start, int end) {
		if (start == end) {
			return false;
		}
		int hour = Calendar.getInstance().get(Calendar.HOUR_OF_DAY);
		int minute = Calendar.getInstance().get(Calendar.MINUTE);
		String strMinute = "";
		if (minute < 10) {
			strMinute = "0" + minute;
		} else {
			strMinute = "" + minute;
		}
		// 当前时间
		int time = Integer.parseInt(hour + "" + strMinute);
		if (start < end) {
			if (time < start || time > end) {
				return false;
			}
		}
		if (time > end && time < start) {
			return false;
		}
		return true;
	}

	/**
	 * <pre>
	 * double的大数据科学计数法转成字符形式，不使用科学计数法
	 * </pre>
	 * 
	 * @param value
	 * @return
	 */
	public static String sicenToComm(double value) {
		NumberFormat nf = NumberFormat.getInstance();
		nf.setGroupingUsed(false);
		return nf.format(value);
	}

	/**
	 * <pre>
	 * 号码转换将01020304转换为01,02,03,04
	 * </pre>
	 * 
	 * @param winCode
	 * @return
	 */
	public static String convertWincode(String winCode) {
		String code = "";
		String st[] = winCode.split(",");
		if (st.length > 1) {
			code = winCode.replaceAll(",", "");
		}
		code = StringUtil.replaceBlank(winCode);
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < code.length(); i = i + 2) {
			sb.append(code.substring(i, i + 2));
			sb.append(",");
		}
		sb.deleteCharAt(sb.length() - 1);
		code = sb.toString();
		return code;
	}

	/**
	 * <pre>
	 * 号码转换将01020304转换为01,02,03,04
	 * </pre>
	 * 
	 * @param winCode
	 * @return
	 */
	public static String convert3DWincode(String winCode) {
		String code = "";
		String st[] = winCode.split(",");
		if (st.length > 1) {
			code = winCode.replaceAll(",", "");
		}
		code = StringUtil.replaceBlank(winCode);
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < code.length(); i = i + 1) {
			sb.append(code.substring(i, i + 1));
			sb.append(",");
		}
		sb.deleteCharAt(sb.length() - 1);
		code = sb.toString();
		return code;
	}

	/**
	 * <pre>
	 * 判断字串是否有值
	 * </pre>
	 * 
	 * @param str
	 *            日期对象
	 * @return boolean
	 */
	public static boolean hasText(String str) {
		if ((str != null) && (str.trim().length() > 0)) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * <pre>
	 * 返回当前的日期
	 * </pre>
	 * 
	 * @return
	 */
	public static String curDate() {
		Calendar now = Calendar.getInstance(TimeZone.getDefault());
		String DATE_FORMAT = "yyyy-MM-dd";
		SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
		sdf.setTimeZone(TimeZone.getDefault());
		return (sdf.format(now.getTime()));
	}

	/**
	 * <pre>
	 * 返回当前的日期后一天即明天
	 * </pre>
	 * 
	 * @return
	 */
	public static String getTomorrow() {
		Calendar now = Calendar.getInstance(TimeZone.getDefault());
		// yesterday
		now.add(Calendar.DAY_OF_MONTH, 1);
		String DATE_FORMAT = "yyyy-MM-dd";
		SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
		sdf.setTimeZone(TimeZone.getDefault());
		return (sdf.format(now.getTime()));
	}

	/**
	 * <pre>
	 * 返回当前的日期的前一个星期的这一天
	 * </pre>
	 * 
	 * @return
	 */
	public static String getDatePreWeek(Date date) {
		Calendar now = Calendar.getInstance(TimeZone.getDefault());
		now.setTime(date);
		// yesterday
		now.add(Calendar.DAY_OF_WEEK_IN_MONTH, -1);
		String DATE_FORMAT = "yyyy-MM-dd";
		SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
		sdf.setTimeZone(TimeZone.getDefault());
		return (sdf.format(now.getTime()));
	}

	/**
	 * <pre>
	 * 返回当前的日期的前一月的这一天
	 * </pre>
	 * 
	 * @return
	 */
	public static String getDatePreMonth(Date date) {
		Calendar now = Calendar.getInstance(TimeZone.getDefault());
		now.setTime(date);
		now.add(Calendar.MONTH, -1);
		String DATE_FORMAT = "yyyy-MM-dd";
		SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
		sdf.setTimeZone(TimeZone.getDefault());
		return (sdf.format(now.getTime()));
	}

	/**
	 * <pre>
	 * 返回当前的日期的前一年的这一天
	 * </pre>
	 * 
	 * @return
	 */
	public static String getDatePreYear(Date date) {
		Calendar now = Calendar.getInstance(TimeZone.getDefault());
		now.setTime(date);
		now.add(Calendar.YEAR, -1);
		String DATE_FORMAT = "yyyy-MM-dd";
		SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
		sdf.setTimeZone(TimeZone.getDefault());
		return (sdf.format(now.getTime()));
	}

	/**
	 * <pre>
	 * 返回当前的日期的前一年的这一天
	 * </pre>
	 * 
	 * @return
	 */
	public static String getDateBeforeDay(Date date) {
		Calendar now = Calendar.getInstance(TimeZone.getDefault());
		now.setTime(date);
		now.add(Calendar.DAY_OF_MONTH, -1);
		String DATE_FORMAT = "yyyy-MM-dd";
		SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
		sdf.setTimeZone(TimeZone.getDefault());
		return (sdf.format(now.getTime()));
	}

	/**
	 * <pre>
	 * 根据指定的格式的字符串创建将日期对象
	 * </pre>
	 * 
	 * @param dateStr
	 *            日期字符串
	 * @param pattern
	 *            格式
	 * @return 日期对象
	 * @throws ParseException
	 *             格式错误
	 */
	public static Date getDateFromString(String dateStr, String pattern) {
		SimpleDateFormat sdf = new SimpleDateFormat(pattern);
		Date date = null;
		try {
			date = sdf.parse(dateStr);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return date;
	}

	/**
	 * <pre>
	 * 返回当前的日期前一天
	 * </pre>
	 * 
	 * @return
	 */
	public static String getYesterday() {
		Calendar now = Calendar.getInstance(TimeZone.getDefault());
		// yesterday
		now.add(Calendar.DAY_OF_MONTH, -1);
		String DATE_FORMAT = "yyyy-MM-dd";
		SimpleDateFormat sdf = new SimpleDateFormat(DATE_FORMAT);
		sdf.setTimeZone(TimeZone.getDefault());
		return (sdf.format(now.getTime()));
	}

	/**
	 * <pre>
	 * 将票号转成十六进制字符串
	 * </pre>
	 * 
	 * @param ticketSerialNo
	 * @return
	 * @throws Exception
	 */
	public static String toHexString(String ticketSerialNo) throws Exception {
		StringBuffer sb = new StringBuffer();
		if (!hasText(ticketSerialNo)) {
			return "";
		}
		try {
			int dev = 5;
			int step = ticketSerialNo.length() % dev == 0 ? ticketSerialNo
					.length()
					/ dev : (ticketSerialNo.length() / dev) + 1;
			for (int i = 0; i < step; i++) {
				int length = i * 5 + 5;
				String str = "";
				if (length > ticketSerialNo.length()) {
					str = ticketSerialNo.substring(i * dev, ticketSerialNo
							.length());
				} else {
					str = ticketSerialNo.substring(i * dev, (i + 1) * dev);
				}
				String hex = Integer.toHexString(Integer.parseInt(str))
						.toUpperCase();
				int hexlength = hex.length();
				if (hex.length() < dev) {
					for (int j = 0; j < dev - hexlength; j++) {
						hex = "0" + hex;
					}
				}
				sb.append(hex + "-");
			}
			sb.deleteCharAt(sb.toString().length() - 1);
		} catch (Exception e) {
			throw new Exception("票号转十六进制出错:" + ticketSerialNo, e);
		}
		return sb.toString();
	}

	public static String getDateString(long timesMillion) {
		SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date d = new Date(timesMillion);
		String s = null;
		s = sf.format(d);
		return s;
	}

	/**
	 * <pre>
	 * 排列组合算法(回溯算法)Cnr
	 * </pre>
	 * 
	 * @param codes
	 * @param n
	 * @param r
	 * @return
	 */
	public static List<String> combine(String codes[], int n, int r) {
		List<String> list = new ArrayList<String>();
		if (r > n) {
			return list;
		}
		int[] order = new int[r + 1];
		for (int i = 0; i <= r; i++) {
			order[i] = i - 1; // 注意这里order[0]=-1用来作为循环判断标识
		}
		int k = r;
		boolean flag = true; // 标志找到一个有效组合
		int count = 0;
		while (order[0] == -1) {
			if (flag) // 输出符合要求的组合
			{
				String code = "";
				for (int i = 1; i <= r; i++) {
					code = code + codes[order[i]] + ",";
				}
				list.add(code.substring(0, code.length() - 1));
				count++;
				flag = false;
			}
			order[k]++; // 在当前位置选择新的数字
			if (order[k] == n) // 当前位置已无数字可选，回溯
			{
				order[k--] = 0;
				continue;
			}
			if (k < r) // 更新当前位置的下一位置的数字
			{
				order[++k] = order[k - 1];
				continue;
			}
			if (k == r) {
				flag = true;
			}
		}
		return list;
	}

	/**
	 * <pre>
	 * 根据指定的格式将日期格式化为字符串
	 * </pre>
	 * 
	 * @param date
	 *            日期对象
	 * @param pattern
	 *            格式
	 * @return 日期字符串
	 * @throws ParseException
	 *             格式错误
	 */
	public static String getStringFromDate(Date date, String pattern) {
		String dateStr = "";
		try {
			SimpleDateFormat sdf = new SimpleDateFormat(pattern);
			dateStr = sdf.format(date);
		} catch (Exception e) {
			dateStr = "";
		}
		return dateStr;
	}

	/**
	 * 删除字符串中的换行符和空格.
	 */
	public static String replaceBlank(String xml) {
		Pattern p = Pattern.compile("\\s*|\t|\r|\n");
		Matcher m = p.matcher(xml);
		String after = m.replaceAll("");
		return after;
	}

	/**
	 * Test the string is null value or null string
	 */
	public static boolean isEmpty(String s) {
		if (null == s || s.trim().length() < 1) {
			return true;
		}
		return false;
	}

	/**
	 * Transform the specified byte into a Hex String form.
	 */
	public static final String bytesToHexStr(byte[] bcd) {
		StringBuffer s = new StringBuffer(bcd.length * 2);

		for (int i = 0; i < bcd.length; i++) {
			s.append(bcdLookup[(bcd[i] >>> 4) & 0x0f]);
			s.append(bcdLookup[bcd[i] & 0x0f]);
		}

		return s.toString();
	}

	/**
	 * Transform the specified Hex String into a byte array.
	 */
	public static final byte[] hexStrToBytes(String s) {
		byte[] bytes;

		bytes = new byte[s.length() / 2];

		for (int i = 0; i < bytes.length; i++) {
			bytes[i] = (byte) Integer.parseInt(s.substring(2 * i, 2 * i + 2),
					16);
		}

		return bytes;
	}

	private static final char[] bcdLookup = { '0', '1', '2', '3', '4', '5',
			'6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
}
